package com.ftg.learn.chapter18;

import com.sun.javafx.scene.control.skin.VirtualFlow;
import com.sun.jmx.snmp.internal.SnmpOutgoingRequest;

import javax.xml.stream.XMLOutputFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * 表达式的复习
 * @author KangJx
 * @date 2021/8/26
 */
public class LearnLambda2 {

//    先来说一个小题
//    计算方式 (两数的计算[+-*/ % sqrt power])

    //下列的方法全是功能比较单一，
//    方法要比较 多，使用起来要记大量的方法名称，
    //接口   三个实现类

    private int add(int x ,int y){
        return x+y;
    }

    private int div(int x ,int y){
        return x - y;
    }

    private double power(int x ,int y){
        return Math.pow(x,y);
    }

//    说实话

    /**
     * 多态： 面向接口编程 接收却是实现类的实例
     *  同一个方法，产生结果不一样
     * @param x
     * @param y
     * @param d
     * @return
     */
    private double newMethod(double x,double y,Deel d){
        return d.dight(x,y);
    }

    public static void main(String[] args) {
        LearnLambda2 ll = new LearnLambda2();
        double sum = ll.newMethod(2,3,new AddClass());
        System.out.println(sum);

        double cha1 = ll.newMethod(21,4,new DivClass());
        System.out.println(cha1);

//        匿名内部类
        double sum1 = ll.newMethod(23, 456, new Deel() {
            @Override
            public double dight(double x, double y) {
                x= x + 13;
                y = y -2;
                return x + y;
            }
        });
        System.out.println(sum1);

        double sum2 = ll.newMethod(2,3,(x,y)-> x+y);
        double sum3 = ll.newMethod(2,3,(x,y)-> x-y);
//    四大常用函数式接口
//        1、消费型  输出 foreach void Consumer
//        2、供给型  创建对象用的 T     Suppiler
//        3、断言型  判断 boolean      Predicate
//        4、函数型  把一判断处理作为方法的参数使用 <T参数类型,R返回值类型> functional
        System.out.println(sum2);
//        这个接口往往都只有一个方法,都要实现类，这个实现类里面的代码比较简单
//        λ  lambda
//        ()-> {statment}
//        (parameter) ->{statment;}

        double t = ll.newMethod1(2,3 ,(b,a)-> a+b );
        System.out.println(t);

        //jdk foreach
        List<String> list = Arrays.asList("a","b");
        list.forEach(x -> System.out.println(x) );

        list.sort((x,y)-> -(x.compareTo(y)));
        System.out.println("--->");
        ll.find(list,x->x.equals("a")).forEach(x-> System.out.println(x));
        //集合联用
//        jdk Stream
       String str =  list.stream().distinct().sorted().filter(x->x.equals("a")).findFirst().get();
    }

    private List<String> find(List<String> list, Predicate<String> c){
        List<String> list1 = new ArrayList<>(3);
        for(String str : list){
            if(c.test(str)){
                list1.add(str);
            }
        }
        return list1;
    }

    private double newMethod1(Integer x, Integer y, BiFunction<Integer, Integer,Integer> t){
        return t.apply(x,y);
    }


}
